package com.bookstore.servlet.cart;

import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.JSONObject;

import com.bookstore.model.CartItem;
import com.bookstore.service.ProductService;
import com.bookstore.service.ServiceFactory;
import com.sun.org.apache.bcel.internal.generic.NEW;

@WebServlet("/car.do")
public class CartServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public static final String METHOD_ADD = "0";
	public static final String METHOD_DELETE = "1";
	public static final String METHOD_EDIT = "2";
	public static final String METHOD_CLEAR = "3";
	public static final String METHOD_LIST = "4";

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String method = request.getParameter("method");
		HttpSession session = request.getSession();
		Map<Integer, CartItem> map = (Map<Integer, CartItem>) session.getAttribute("s_car");
		if (method != null) {
			switch (method) {
			case CartServlet.METHOD_ADD:
				try {
					add(request, response);
				} catch (Exception e) {
					e.printStackTrace();
				}
				break;
			case CartServlet.METHOD_LIST:
				list(request, response, map);
				break;
			case CartServlet.METHOD_DELETE:
				map.remove(new Integer(request.getParameter("id")));
				list(request, response, map);
				break;
			case CartServlet.METHOD_EDIT:
				String num = request.getParameter("num");
				Integer id = new Integer(request.getParameter("id"));
				CartItem cartItem = map.get(id);
				cartItem.setNum(new Integer(num).intValue());
				map.put(id, cartItem);
				response.sendRedirect("/BookStore/car.do?method=4");
				break;
			case CartServlet.METHOD_CLEAR:
				map.clear();
				list(request, response, map);
				break;
			}
		}
	}

	private void add(HttpServletRequest request, HttpServletResponse response) throws Exception {
		boolean flag = true;
		Map<Integer, CartItem> map = null;
		try {
			Integer id = new Integer(request.getParameter("id"));
			HttpSession session = request.getSession();

			if (session.getAttribute("s_user") == null) {
				flag = false;
			} else {
				map = (Map<Integer, CartItem>) session.getAttribute("s_car");
				if (map == null) {
					map = new HashMap<>();
				}
				if (map.containsKey(id)) {
					CartItem cartItem = map.get(id);
					cartItem.setNum(cartItem.getNum() + 1);
				} else {
					CartItem cartItem = new CartItem();
					ProductService productService = ServiceFactory.getProductService();
					cartItem.setPro(productService.findById(id));
					map.put(id, cartItem);
				}
			}
			session.setAttribute("s_car", map);
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("flag", flag);
			PrintWriter out = response.getWriter();
			out.print(jsonObject.toString());
			out.close();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}

	}

	private void list(HttpServletRequest request, HttpServletResponse response, Map<Integer, CartItem> map)
			throws ServletException, IOException {
		request.setAttribute("totalDang", total(map, false));
		request.setAttribute("totalSave", totalSave(total(map, true) - total(map, false)));
		request.setAttribute("s_car", map);
		request.getRequestDispatcher("/WEB-INF/view/car/cart_list.jsp").forward(request, response);
	}

	private double totalSave(double totalSave) {
		BigDecimal bigDecimal = new BigDecimal(totalSave);
		BigDecimal bd = bigDecimal.setScale(2, bigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

	private double total(Map<Integer, CartItem> map, boolean flag) {
		double totalPrice = 0.0;
		if (flag) {
			for (Map.Entry<Integer, CartItem> entry : map.entrySet()) {
				totalPrice += entry.getValue().getNum() * entry.getValue().getPro().getFixedPrice();
			}
		} else {
			for (Map.Entry<Integer, CartItem> entry : map.entrySet()) {
				totalPrice += entry.getValue().getNum() * entry.getValue().getPro().getDangPrice();
			}
		}
		BigDecimal bigDecimal = new BigDecimal(totalPrice);
		BigDecimal bd = bigDecimal.setScale(2, bigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

}
